﻿using KeyboardArg;
using KXmlUIControl.KControl;
using LogLib;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;
using Button = System.Windows.Forms.Button;
using Label = System.Windows.Forms.Label;
using TextBox = System.Windows.Forms.TextBox;

namespace KXmlUIControl
{
    public class XmlConfigForm
    {
        /// <summary>
        /// 最新错误信息
        /// </summary>
        public string Error { get; private set; }

        public bool ContainsGroup { private set; get; } = false;
        public XmlFormObject FormConfig { private set; get; } = new XmlFormObject();
        public XmlCountdownObject CountdownConfig { private set; get; } = new XmlCountdownObject();
        public List<XmlButtonObject> ListButtons { private set; get; } = new List<XmlButtonObject>();
        public List<XmlButtonObject> ListBaseButtons { private set; get; } = new List<XmlButtonObject>();
        public List<XmlLabelObject> ListLabels { private set; get; } = new List<XmlLabelObject>();
        public List<XmlTextBoxObject> ListTextBoxs { private set; get; } = new List<XmlTextBoxObject>();
        public List<XmlPictureBoxObject> ListPicBoxs { private set; get; } = new List<XmlPictureBoxObject>();
        public List<XmlImageObject> ListImages { private set; get; } = new List<XmlImageObject>();
        public List<XmlPanelObject> ListPanels { private set; get; } = new List<XmlPanelObject>();
        public List<XmlKCheckBoxObject> ListCheckBoxs { private set; get; } = new List<XmlKCheckBoxObject>();
        public List<XmlGroupObject> Groups { private set; get; } = new List<XmlGroupObject>();     
        public List<XmlPromptObject> ListPrompts { private set; get; } = new List<XmlPromptObject>();
        public WindowType FormType { set; get; } = WindowType.PageUserControl;
        public Dictionary<string, KeyBoardArgs> InputtingBindings
        {
            private set;
            get;
        } = new Dictionary<string, KeyBoardArgs>();

        private XElement _root = null;
        public List<Control> Controls { private set; get; } = new List<Control>();

        /// <summary>
        /// 父窗体
        /// </summary>
        public ContainerControl ParentContainer { set; get; }
        public bool IsMainForm { private set; get; } = true;
        public XmlConfigForm(XElement e, bool isMainForm)
        {
            _root = e;
            IsMainForm = isMainForm;
        }

        public void LoadConfig()
        {
            if (_root == null)
            {
                return;
            }
            Error = "";
            FormConfig = KXmlParser.GetXmlObject<XmlFormObject>(_root, "Form");
            CountdownConfig = KXmlParser.GetXmlObject<XmlCountdownObject>(_root, "CountdownControl");
            ListBaseButtons = KXmlParser.GetXmlObject<XmlButtonObject>(_root, "BaseButtons", "Button");
            ListButtons = KXmlParser.GetXmlObject<XmlButtonObject>(_root, "Buttons", "Button");
            ListLabels = KXmlParser.GetXmlObject<XmlLabelObject>(_root, "Labels", "Label");
            ListPicBoxs = KXmlParser.GetXmlObject<XmlPictureBoxObject>(_root, "PictureBoxs", "PictureBox");
            ListTextBoxs = KXmlParser.GetXmlObject<XmlTextBoxObject>(_root, "TextBoxs", "TextBox");
            ListImages = KXmlParser.GetXmlObject<XmlImageObject>(_root, "Images", "Image");
            ListPanels = KXmlParser.GetXmlObject<XmlPanelObject>(_root, "Panels", "Panel");
            ListCheckBoxs = KXmlParser.GetXmlObject<XmlKCheckBoxObject>(_root, "CheckBoxs", "CheckBox");
            ListPrompts = KXmlParser.GetXmlObject<XmlPromptObject>(_root, "Prompts", "Prompt");
            LoadGroupConfig();
        }

        private void LoadGroupConfig()
        {
            Error = "";
            Groups.Clear();
            XElement parent = _root.Element("Groups");
            if (parent == null)
            {
                ContainsGroup = false;
                Error = "Groups节点为空.";
                return;
            }
            IEnumerable<XElement> elems = parent.Elements("Group");
            if (elems == null)
            {
                ContainsGroup = false;
                return;
            }
            if (elems.Count() == 0)
            {
                ContainsGroup = false;
                return;
            }
            try
            {
                foreach (XElement e in elems)
                {
                    XmlGroupObject group = KXmlParser.ParseXMLObject<XmlGroupObject>(e);
                    IEnumerable<XElement> childElems = e.Elements("add");
                    if (childElems != null && childElems.Count() > 0)
                    {
                        foreach (XElement childElem in childElems)
                        {
                            XmlGroupMemberObject member = KXmlParser.ParseXMLObject<XmlGroupMemberObject>(childElem);
                            group.Add(member);
                        }
                    }
                    Groups.Add(group);
                }
                ContainsGroup = true;
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
                Log.WriteException(ex.ToString());
                ContainsGroup = false;
            }
        }

        public CountdownControl CreatCountdownControl()
        {
            CountdownControl value = (CountdownControl)CountdownConfig.ToControl(ParentContainer);
            return value;
        }

        public void ApplyCountdownControl(CountdownControl control)
        {
            CountdownConfig.SetValues(control);
        }

        public List<Panel> CreatPanels()
        {
            List<Panel> list = new List<Panel>();
            if (ListPanels == null || ListPanels.Count == 0)
            {
                return list;
            }
            foreach (XmlPanelObject pan in ListPanels)
            {
                Panel value = (Panel)pan.ToControl(ParentContainer);
                list.Add(value);
            }
            if (list.Count > 0)
            {
                Controls.AddRange(list);
            }
            return list;
        }

        public void ApplyPanels(List<Panel> panels)
        {
            Panel panel = null;
            for (int i = 0; i < panels.Count; i++)
            {
                panel = panels[i];
                XmlPanelObject config = ListPanels.Find(r => r.Name.Equals(panel.Name));
                if (config != null)
                {
                    config.SetValues(panel);
                }
            }
        }

        public Dictionary<string, XmlPromptObject> LoadPrompts()
        {
            Dictionary<string, XmlPromptObject> dic = new Dictionary<string, XmlPromptObject>();
            foreach (XmlPromptObject prompt in ListPrompts)
            {
                dic.Add(prompt.Name, prompt);
            }

            return dic;
        }

        public List<Button> CreatBaseButtons()
        {
            List<Button> list = new List<Button>();
            foreach (XmlButtonObject btn in ListBaseButtons)
            {
                Button value = (Button)btn.ToControl(ParentContainer);
                list.Add(value);
            }
            Controls.AddRange(list);
            return list;
        }

        public void ApplyBaseButtons(List<Button> buttons)
        {
            Button button = null;
            for (int i = 0; i < buttons.Count; i++)
            {
                button = buttons[i];
                XmlButtonObject config = ListBaseButtons.Find(r => r.Name.Equals(button.Name));
                if (config != null)
                {
                    config.SetValues(button);
                }
            }
        }

        public List<TextBox> CreatTextBoxs()
        {
            List<TextBox> list = new List<TextBox>();
            foreach (XmlTextBoxObject tb in ListTextBoxs)
            {
                TextBox ctl = tb.ToControl(ParentContainer) as TextBox;
                list.Add(ctl);
                KeyBoardArgs arg = new KeyBoardArgs();
                arg.NotNull = tb.NotNull;
                arg.MaxLength = tb.GetMaxLength();
                arg.Key = tb.Tag;
                arg.Title = tb.ToolTip;
                arg.LanguageCode = FormConfig.LanguageCode;
                arg.DictionaryFileName = tb.KeyBoard;
                arg.VoiceFileName = tb.Voice;
                InputtingBindings.Add(tb.Name, arg);
            }
            Controls.AddRange(list);
            return list;
        }

        public void ApplyTextBoxs(List<TextBox> textBoxs)
        {
            TextBox textBox = null;
            for (int i = 0; i < textBoxs.Count; i++)
            {
                textBox = textBoxs[i];
                XmlTextBoxObject config = ListTextBoxs.Find(r => r.Name.Equals(textBox.Name));
                if (config != null)
                {
                    config.SetValues(textBox);
                }
            }
        }

        public List<Label> CreatLabels()
        {
            List<Label> list = new List<Label>();
            foreach (XmlLabelObject label in ListLabels)
            {
                list.Add((Label)label.ToControl(ParentContainer));
            }
            Controls.AddRange(list);
            return list;
        }

        public void ApplyLabels(List<Label> labels)
        {
            Label label = null;
            for (int i = 0; i < labels.Count; i++)
            {
                label = labels[i];
                XmlLabelObject config = ListLabels.Find(r => r.Name.Equals(label.Name));
                if (config != null)
                {
                    config.SetValues(label);
                }
            }
        }

        public List<PictureBox> CreatPictureBoxs()
        {
            List<PictureBox> list = new List<PictureBox>();
            foreach (XmlPictureBoxObject pic in ListPicBoxs)
            {
                list.Add((PictureBox)pic.ToControl(ParentContainer));
            }
            Controls.AddRange(list);
            return list;
        }

        public void ApplyPictureBoxs(List<PictureBox> pictureBoxs)
        {
            PictureBox pictureBox = null;
            for (int i = 0; i < pictureBoxs.Count; i++)
            {
                pictureBox = pictureBoxs[i];
                XmlPictureBoxObject config = ListPicBoxs.Find(r => r.Name.Equals(pictureBox.Name));
                if (config != null)
                {
                    config.SetValues(pictureBox);
                }
            }
        }

        public List<Button> CreatButtons()
        {
            List<Button> list = new List<Button>();
            foreach (XmlButtonObject btn in ListButtons)
            {
                list.Add((Button)btn.ToControl(ParentContainer));
            }
            Controls.AddRange(list);
            return list;
        }

        public void ApplyButtons(List<Button> buttons)
        {
            Button button = null;
            for (int i = 0; i < buttons.Count; i++)
            {
                button = buttons[i];
                XmlButtonObject config = ListButtons.Find(r => r.Name.Equals(button.Name));
                if (config != null)
                {
                    config.SetValues(button);
                }
            }
        }

        public List<KCheckBox> CreatKCheckBoxs()
        {
            List<KCheckBox> list = new List<KCheckBox>();
            foreach (XmlKCheckBoxObject cb in ListCheckBoxs)
            {
                list.Add((KCheckBox)cb.ToControl(ParentContainer));
            }
            Controls.AddRange(list);
            return list;
        }

        public void ApplyKCheckBoxs(List<KCheckBox> list)
        {
            KCheckBox cb = null;
            for (int i = 0; i < list.Count; i++)
            {
                cb = list[i];
                XmlKCheckBoxObject config = ListCheckBoxs.Find(r => r.Name.Equals(cb.Name));
                if (config != null)
                {
                    config.SetValues(cb);
                }
            }
        }

        public List<Image> LoadImages()
        {
            List<Image> list = new List<Image>();
            foreach (XmlImageObject mi in ListImages)
            {
                Image image = mi.GetImage();
                if (image != null)
                {
                    list.Add(image);
                }
            }
            return list;
        }
    }
}
